import java.util.ArrayList;
import java_cup.runtime.*;

%%

%implements java_cup.runtime.Scanner
%function next_token
%type java_cup.runtime.Symbol

%class AnalizadorLexico

%line

%init{
    
%init}

%eofval{
    return new Symbol(sym.EOF);
%eofval}

%{

    public static ArrayList <String> erroresLexicos;

    StringBuffer string = new StringBuffer();
    /*
    Clases lexicas

    CLASE LEXICA                TIPO
    if      (PR)                1
    while   (PR)                2
    else    (PR)                3
    int     (PR)                4
    float   (PR)                5
    char    (PR)                6
    break   (PR)                7
    print   (PR)                8
    read    (PR)                9
    void    (PR)                10
    return  (PR)                11
    constantes (cadenas)        12
    id      (ID)                13
    entero                      14
    flotante                    15
    caracter                    16
    comentario_una_linea
    comentarios_varias_lineas
    +
    -
    *
    /
    %
    <, >, <=, >=, ==, !=
    ||, &&, !
    =
    (
    )
    [
    ]
    {
    }
    ;
    ,
    */

%}


may = [A-Z]
min = [a-z]
dig = [0-9]
blanco = [ \t\r\n]

%state CADENA CARACTER


%%

<YYINITIAL> if                                      {return new Symbol(sym.IF);}
<YYINITIAL> while                                   {return new Symbol(sym.WHILE);}
<YYINITIAL> else                                    {return new Symbol(sym.ELSE);}
<YYINITIAL> int                                     {return new Symbol(sym.INT);}
<YYINITIAL> float                                   {return new Symbol(sym.FLOAT);}
<YYINITIAL> char                                    {return new Symbol(sym.CHAR);}
<YYINITIAL> break                                   {return new Symbol(sym.BREAK);}
<YYINITIAL> print                                   {return new Symbol(sym.PRINT);}
<YYINITIAL> read                                    {return new Symbol(sym.READ);}
<YYINITIAL> void                                    {return new Symbol(sym.VOID);}
<YYINITIAL> return                                  {return new Symbol(sym.RETURN);}

<YYINITIAL> {
    \"                                      {
                                                string.setLength(0);
                                                string.append("\"");
                                                yybegin(CADENA);
                                            }
    \'                                      {
                                                string.setLength(0);
                                                string.append("\'");
                                                yybegin(CARACTER);
                                            }
    (_|{may}|{min})(_|{may}|{min}|{dig})*   {return new Symbol(sym.ID,yytext());}
    ({dig}|[1-9]{dig}*)                     {return new Symbol(sym.ENTERO,Integer.parseInt(yytext()));}
    ({dig}*)?\.{dig}*                       {return new Symbol(sym.REAL,Float.parseFloat(yytext()));}
    \/\/.*\n                                {/*Ignorar*/}
    "/*"~"*/"                               {/*Ignorar*/}
    \+                                      {return new Symbol(sym.MAS);}
    -                                       {return new Symbol(sym.MENOS);}
    \*                                      {return new Symbol(sym.MULT);}
    \/                                      {return new Symbol(sym.DIV);}
    %                                       {return new Symbol(sym.MOD);}
    "<"                                     {return new Symbol(sym.MENOR);}
    ">"                                     {return new Symbol(sym.MAYOR);}
    "<="                                    {return new Symbol(sym.MENORISO);}
    ">="                                    {return new Symbol(sym.MAYORISO);}
    "=="                                    {return new Symbol(sym.EQUAL);}
    "!="                                    {return new Symbol(sym.DIFF);}
    \|\|                                    {return new Symbol(sym.AND);}
    "&&"                                    {return new Symbol(sym.OR);}
    =                                       {return new Symbol(sym.IGUAL);}
    \(                                      {return new Symbol(sym.PARIZQ);}
    \)                                      {return new Symbol(sym.PARDER);}
    \[                                      {return new Symbol(sym.CORIZQ);}
    \]                                      {return new Symbol(sym.CORDER);}
    \{                                      {return new Symbol(sym.LLAVEIZQ);}
    \}                                      {return new Symbol(sym.LLAVEDER);}
    ;                                       {return new Symbol(sym.PTOYCOMA);}
    ,                                       {return new Symbol(sym.COMA);}
}

<CADENA> {
            \"                          {
                                            yybegin(YYINITIAL);
                                            return new Symbol(sym.CADENA,string+yytext());
                                        }
            [^\n\r\"\\]+                {
                                            string.append(yytext());
                                        }
            [\n\r]                      {
                                            yybegin(YYINITIAL);
                                            CompiladorC.erroresLexicos.add("Error lexico en"+
                                            " la linea "+(yyline+1)+" por : "+string.toString());                       
                                        }
}

<CARACTER> {
            .\'                         {
                                            yybegin(YYINITIAL);
                                            return new Symbol(sym.CARACTER,yytext());
                                        }
            .                           {
                                            yybegin(YYINITIAL);
                                            CompiladorC.erroresLexicos.add("Error lexico en"+
                                            " la linea "+(yyline+1)+" por : "+string.toString()+yytext());
                                        }
}

{blanco}                                {/*Ignorar*/}
.                                       {
                                            /*ERROR*/
                                            CompiladorC.erroresLexicos.add("Error lexico en"+
                                            " la linea "+(yyline+1)+" por : "+yytext());
                                        }
                                        